/*
* $Id: SettingStore.java 234 2010-12-29 13:37:20Z volokaleks@yandex.ru $
*
* Copyright 2008-2010 by Volokitin Alexey
* All rights reserved
*
*/
package apiary.settings;

import apiary.settings.SettingsRecord.Field;

import java.io.*;
import java.util.*;
import javax.microedition.rms.*;

/**
 * Representing a record storage of application settings
 * @author lexus
 */
public class SettingStore
{
    /** name of storage */
    private static final String SETTING_STORE = "settings_store";

    /** Instance class */
    private static SettingStore instance = null;
    /**
     * Gets instance class
     */
    public static SettingStore getInstance(){
        if(instance == null)
            instance = new SettingStore();
        return instance;
    }

    /** List of settings */
    private Hashtable settingRecords;
    /** Storage */
    private RecordStore store;

    /**
     * Contructor
     */
    public SettingStore(){
        instance = this;
        settingRecords = new Hashtable();
        try{
            store = RecordStore.openRecordStore(SETTING_STORE, true, RecordStore.AUTHMODE_ANY, false);
            readStorage();
            store.closeRecordStore();
        }catch(RecordStoreException ex){
        }
        store = null;
    }

    /**
     * Gets data of parameter by name
     * @param name name of parameter
     * @return data of parameter
     */
    public Field getData(int name) {
        return getData(new Integer(name));
    }
    /**
     * Gets data of parameter by name
     * @param name name of parameter
     * @return data of parameter
     */
    public Field getData(Integer name){
        if(!settingRecords.containsKey(name))
            settingRecords.put(name, new SettingsRecord(name));
        SettingsRecord record = (SettingsRecord) settingRecords.get(name);
        return record.field;
    }
    /**
     * Sets data of parameter by name
     * @param name name of parameter
     * @param value data of parameter
     */
    public void setData(Integer name, Object value){
        if(!settingRecords.containsKey(name))
            settingRecords.put(name, new SettingsRecord(name));
        SettingsRecord record = (SettingsRecord) settingRecords.get(name);
        record.field.setValue(value);
    }

    /**
     * Saves all changes
     */
    public void saveData() {
        try {
            store = RecordStore.openRecordStore(SETTING_STORE, true);
            Enumeration elements = settingRecords.elements();
            while (elements.hasMoreElements()) {
                SettingsRecord element = (SettingsRecord) elements.nextElement();
                if (element.field.isValid()) {
                    saveField(element.name, element.field);
                }
            }
            store.closeRecordStore();
        } catch (RecordStoreException ex) {}
        store = null;
    }

    /**
     * Saves data of parameter by name
     * @param id name of parameter
     * @param field data of parameter
     */
    private void saveField(Integer id, Field field) throws RecordStoreException{
        String value;
        if (field.getTypeValue().intValue() == SettingsRecord.TYPE_VALUE_DATE) {
            Date date = (Date) field.getValue();
            Long time = new Long(date.getTime());
            value = time.toString();
        } else {
            value = field.getValue().toString();
        }
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeInt(id.intValue());
            dos.writeInt(field.getTypeValue().intValue());
            dos.writeUTF(value);
            byte[] record = baos.toByteArray();
            if (field.isRecord()) {
                store.setRecord(field.getIdRecord().intValue(), record, 0, record.length);
            } else {
                field.setIdRecord(store.addRecord(record, 0, record.length));
            }
        } catch (IOException ex) {
        }
    }

    /**
     * Reads settings from storage
     */
    private void readStorage() throws RecordStoreNotOpenException,
                                      RecordStoreException {
        RecordEnumeration enumerator = store.enumerateRecords (null, null, false);
        while(enumerator.hasNextElement()){
            int id = enumerator.nextRecordId();
            byte[] data = store.getRecord(id);
            try {
                ByteArrayInputStream bais = new ByteArrayInputStream(data);
                DataInputStream dis = new DataInputStream(bais);
                Integer name = new Integer(dis.readInt());
                Integer typeValue = new Integer(dis.readInt());
                String val = dis.readUTF();
                SettingsRecord record = null;
                if (!settingRecords.containsKey(name)) {
                    record = new SettingsRecord(name);
                    settingRecords.put(name, record);
                } else {
                    record = (SettingsRecord) settingRecords.get(name);
                }
                Field field = record.new Field(new Integer(id), typeValue, val);
                record.setField(field);
            } catch (IOException ex) {}
        }
    }
}
